package peer.model.transfer.file;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import peer.model.consts.TransferConsts;
import peer.model.transfer.Codec;
import peer.util.TransferUtil;

/**
 * Utility class which sends files.
 * @author Guido
 */

public class FileSender {

	public static void sendFile(Socket socket, File file){
		FileInputStream fileInput=null;
		try {
			OutputStream output = socket.getOutputStream();

			/*Transfer the metadata*/
			sendSize(output, file.getName().length());
			send(new ByteArrayInputStream(file.getName().getBytes()), output, TransferConsts.MEGA_BYTE, file.getName().length());

			/*Transfer the file*/
			sendSize(output, file.length());
			int partitions = TransferUtil.partition(file.length());
			fileInput = new FileInputStream(file);

			for(int i = 0; i < partitions; i++){
				send(fileInput, output, TransferConsts.MEGA_BYTE, TransferConsts.TRANSFER_BUFFER_SIZE);
			}

			send(fileInput, output, TransferConsts.MEGA_BYTE, (int) (file.length() - partitions * TransferConsts.TRANSFER_BUFFER_SIZE));

		} catch (IOException e) {
			e.printStackTrace(System.err);
		}finally{
			try {
				fileInput.close();
			} catch (IOException e) {
				e.printStackTrace(System.err);
			}
		}
	}

	public static void sendSize(OutputStream output, long size){
		send(new ByteArrayInputStream(Codec.encode(size)), output, Codec.SIZE_BYTES, Codec.SIZE_BYTES);
	}


	public static void send(InputStream input, OutputStream output, int bufferSize, int dataSize){
		byte[] buffer = new byte[bufferSize];
		int sent = 0;
		int readed = 0;

		try {
			while((readed = input.read(buffer, 0, (int)	Math.min(dataSize - sent, bufferSize))) > 0){
				output.write(buffer, 0, readed);
				sent += readed;
			}
		} catch (IOException e) {
			e.printStackTrace(System.err);
		}
	}








//	public static void sendFile(Socket socket, File file){
//		FileInputStream fileInput=null;
//		try {
//			OutputStream output = socket.getOutputStream();
//
//			/*Transfer the metadata*/
//			sendSize(output, file.getName().length());
//			send(new ByteArrayInputStream(file.getName().getBytes()), output, TransferConsts.MEGA_BYTE, file.getName().length());
//
//			/*Transfer the file*/
//			sendSize(output, file.length());
//			int partitions = TransferUtil.partition(file.length());
//			fileInput = new FileInputStream(file);
//
//			for(int i = 0; i < partitions; i++){
//				send(fileInput, output, TransferConsts.MEGA_BYTE, TransferConsts.PARTITION_SIZE);
//			}
//
//			send(fileInput, output, TransferConsts.MEGA_BYTE, (int) (file.length() - partitions * TransferConsts.PARTITION_SIZE));
//
//		} catch (IOException e) {
//			e.printStackTrace(System.err);
//		}finally{
//			try {
//				fileInput.close();
//			} catch (IOException e) {
//				e.printStackTrace(System.err);
//			}
//		}
//	}
//
//	public static void sendSize(OutputStream output, long size){
//		send(new ByteArrayInputStream(Codec.encode(size)), output, Codec.SIZE_BYTES, Codec.SIZE_BYTES);
//	}
//
//
//	public static void send(InputStream input, OutputStream output, int bufferSize, int dataSize){
//		byte[] buffer = new byte[bufferSize];
//		int sent = 0;
//		int readed = 0;
//
//		try {
//			while((readed = input.read(buffer, 0, (int)	Math.min(dataSize - sent, bufferSize))) > 0){
//				output.write(buffer, 0, readed);
//				sent += readed;
//			}
//		} catch (IOException e) {
//			e.printStackTrace(System.err);
//		}
//	}

}
